home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / libs / libelf-0.5 / libelf-0 / libelf-0.5.2 / cook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-19  |  5.8 KB  |  240 lines

  1. /*
  2. cook.c - read and translate ELF files.
  3. Copyright (C) 1995 Michael Riepe <riepe@ifwsn4.ifw.uni-hannover.de>
  4.  
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9.  
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #include <private.h>
  21.  
  22. const Elf_Scn _elf_scn_init = INIT_SCN;
  23. const Scn_Data _elf_data_init = INIT_DATA;
  24.  
  25. const Elf_Type _elf_scn_types[SHT_NUM] = {
  26.     /* SHT_NULL */    ELF_T_BYTE,
  27.     /* SHT_PROGBITS */    ELF_T_BYTE,
  28.     /* SHT_SYMTAB */    ELF_T_SYM,
  29.     /* SHT_STRTAB */    ELF_T_BYTE,
  30.     /* SHT_RELA */    ELF_T_RELA,
  31.     /* SHT_HASH */    ELF_T_WORD,
  32.     /* SHT_DYNAMIC */    ELF_T_DYN,
  33.     /* SHT_NOTE */    ELF_T_BYTE,
  34.     /* SHT_NOBITS */    ELF_T_BYTE,
  35.     /* SHT_REL */    ELF_T_REL,
  36.     /* SHT_SHLIB */    ELF_T_BYTE,
  37.     /* SHT_DYNSYM */    ELF_T_SYM
  38. };
  39.  
  40. #define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR:    \
  41.             ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR:    \
  42.             ((t)==ELF_T_SHDR?ERROR_TRUNC_SHDR:    \
  43.             ERROR_INTERNAL)))
  44. #define memerr(t)   ((t)==ELF_T_EHDR?ERROR_MEM_EHDR:    \
  45.             ((t)==ELF_T_PHDR?ERROR_MEM_PHDR:    \
  46.             ((t)==ELF_T_SHDR?ERROR_MEM_SHDR:    \
  47.             ERROR_INTERNAL)))
  48.  
  49. static char*
  50. _elf32_item(Elf *elf, Elf_Type type, unsigned n, size_t off, int *flag) {
  51.     Elf_Data src, dst;
  52.  
  53.     *flag = 0;
  54.     elf_assert(n);
  55.     elf_assert(valid_type(type));
  56.     if (off < 0 || off > elf->e_size) {
  57.     seterr(ERROR_OUTSIDE);
  58.     return NULL;
  59.     }
  60.  
  61.     src.d_type = type;
  62.     src.d_version = elf->e_version;
  63.     src.d_size = n * _fsize32(src.d_version, type);
  64.     elf_assert(src.d_size);
  65.     if (off + src.d_size > elf->e_size) {
  66.     seterr(truncerr(type));
  67.     return NULL;
  68.     }
  69.  
  70.     dst.d_version = _elf_version;
  71.     dst.d_size = n * _msize32(dst.d_version, type);
  72.     elf_assert(dst.d_size);
  73.  
  74.     elf_assert(elf->e_data);
  75.     if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) {
  76.     dst.d_buf = elf->e_data + off;
  77.     }
  78.     else if (!(dst.d_buf = malloc(dst.d_size))) {
  79.     seterr(memerr(type));
  80.     return NULL;
  81.     }
  82.     else {
  83.     *flag |= 1;
  84.     }
  85.  
  86.     if (elf->e_rawdata) {
  87.     src.d_buf = elf->e_rawdata + off;
  88.     }
  89.     else {
  90.     if (src.d_size <= dst.d_size) {
  91.         src.d_buf = dst.d_buf;
  92.     }
  93.     else if (!(src.d_buf = malloc(src.d_size))) {
  94.         seterr(ERROR_IO_2BIG);
  95.         goto fail;
  96.     }
  97.     else {
  98.         *flag |= 2;
  99.     }
  100.  
  101.     if (!_elf_read(elf, src.d_buf, off, src.d_size)) {
  102.         goto fail;
  103.     }
  104.     }
  105.  
  106.     if (elf32_xlatetom(&dst, &src, elf->e_encoding)) {
  107.     if (*flag & 2) {
  108.         free(src.d_buf);
  109.     }
  110.     if (!(*flag &= 1)) {
  111.         elf->e_cooked = 1;
  112.     }
  113.     return (char*)dst.d_buf;
  114.     }
  115.  
  116. fail:
  117.     if (*flag & 2) {
  118.     free(src.d_buf);
  119.     }
  120.     if (*flag & 1) {
  121.     free(dst.d_buf);
  122.     }
  123.     *flag = 0;
  124.     return NULL;
  125. }
  126.  
  127. #undef truncerr
  128. #undef memerr
  129.  
  130. static int
  131. _elf32_cook(Elf *elf) {
  132.     Elf_Scn *head, *scn;
  133.     Elf32_Ehdr *ehdr;
  134.     Elf32_Shdr *shdr;
  135.     Scn_Data *data;
  136.     Scn_Data *sd;
  137.     unsigned i;
  138.     int flag;
  139.  
  140.     elf->e_ehdr = _elf32_item(elf, ELF_T_EHDR, 1, 0, &flag);
  141.     if (!(ehdr = (Elf32_Ehdr*)elf->e_ehdr)) {
  142.     return 0;
  143.     }
  144.     if (flag) {
  145.     elf->e_free_ehdr = 1;
  146.     }
  147.     if (ehdr->e_phnum && ehdr->e_phoff) {
  148.     elf->e_phdr = _elf32_item(elf, ELF_T_PHDR, ehdr->e_phnum, ehdr->e_phoff, &flag);
  149.     if (!elf->e_phdr) {
  150.         return 0;
  151.     }
  152.     if (flag) {
  153.         elf->e_free_phdr = 1;
  154.     }
  155.     elf->e_phnum = ehdr->e_phnum;
  156.     }
  157.     if (ehdr->e_shnum && ehdr->e_shoff) {
  158.     unsigned tmp = _elf_version;
  159.  
  160.     elf_assert(_msize32(_elf_version, ELF_T_SHDR) <= sizeof(*shdr));
  161.     _elf_version = EV_CURRENT;
  162.     elf_assert(_msize32(_elf_version, ELF_T_SHDR) == sizeof(*shdr));
  163.     elf->e_shdr = _elf32_item(elf, ELF_T_SHDR, ehdr->e_shnum, ehdr->e_shoff, &flag);
  164.     _elf_version = tmp;
  165.     if (!elf->e_shdr) {
  166.         return 0;
  167.     }
  168.     if (flag) {
  169.         elf->e_free_shdr = 1;
  170.     }
  171.     head = (Elf_Scn*)malloc(ehdr->e_shnum * (sizeof(*head) + sizeof(*data)));
  172.     if (!head) {
  173.         seterr(ERROR_MEM_SCN);
  174.         return 0;
  175.     }
  176.     data = (Scn_Data*)(head + ehdr->e_shnum);
  177.     for (scn = NULL, i = ehdr->e_shnum; i-- > 0; ) {
  178.         head[i] = _elf_scn_init;
  179.         head[i].s_link = scn;
  180.         if (!scn) {
  181.         elf->e_scn_n = head + i;
  182.         }
  183.         shdr = (Elf32_Shdr*)elf->e_shdr + i;
  184.         scn = head + i;
  185.         sd = data + i;
  186.  
  187.         scn->s_elf = elf;
  188.         scn->s_shdr = (char*)shdr;
  189.         scn->s_index = i;
  190.         scn->s_data_1 = sd;
  191.         scn->s_data_n = sd;
  192.         scn->s_type = shdr->sh_type;
  193.         scn->s_size = shdr->sh_size;
  194.         scn->s_offset = shdr->sh_offset;
  195.  
  196.         *sd = _elf_data_init;
  197.         sd->sd_scn = scn;
  198.  
  199.         if (valid_scntype(shdr->sh_type)) {
  200.         sd->sd_data.d_type = _elf_scn_types[shdr->sh_type];
  201.         }
  202.         else {
  203.         sd->sd_data.d_type = ELF_T_BYTE;
  204.         }
  205.         sd->sd_data.d_size = shdr->sh_size;
  206.         sd->sd_data.d_align = shdr->sh_addralign;
  207.         sd->sd_data.d_version = _elf_version;
  208.     }
  209.     elf->e_scn_1 = head;
  210.     head->s_freeme = 1;
  211.     }
  212.     return 1;
  213. }
  214.  
  215. int
  216. _elf_cook(Elf *elf) {
  217.     elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
  218.     elf_assert(_elf_data_init.sd_magic == DATA_MAGIC);
  219.     elf_assert(elf);
  220.     elf_assert(elf->e_magic == ELF_MAGIC);
  221.     elf_assert(elf->e_kind == ELF_K_ELF);
  222.     elf_assert(!elf->e_ehdr);
  223.     if (!valid_version(elf->e_version)) {
  224.     seterr(ERROR_UNKNOWN_VERSION);
  225.     }
  226.     else if (!valid_encoding(elf->e_encoding)) {
  227.     seterr(ERROR_UNKNOWN_ENCODING);
  228.     }
  229.     else if (elf->e_class == ELFCLASS32) {
  230.     return _elf32_cook(elf);
  231.     }
  232.     else if (valid_class(elf->e_class)) {
  233.     seterr(ERROR_UNIMPLEMENTED);
  234.     }
  235.     else {
  236.     seterr(ERROR_UNKNOWN_CLASS);
  237.     }
  238.     return 0;
  239. }
  240.